home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 2000 #4 / Amiga Plus CD - 2000 - No. 4.iso / Tools / Treiber / Misc / Mroocheck / FreeWheel / Source / Scroll.c < prev    next >
C/C++ Source or Header  |  2000-04-20  |  6KB  |  265 lines

  1. #include <stdio.h>
  2.  
  3. #include <exec/types.h>
  4.  
  5. #include <intuition/intuitionbase.h>
  6. #include <intuition/intuition.h>
  7. #include <intuition/screens.h>
  8. #include <graphics/clip.h>
  9. #include <devices/inputevent.h>
  10.  
  11. #include <clib/exec_protos.h>
  12. #include <clib/intuition_protos.h>
  13. #include <clib/layers_protos.h>
  14.  
  15. #include "WheelMouse.h"
  16.  
  17. #include "Scroll.h"
  18. #include "RawKey.h"
  19.  
  20. extern struct IntuitionBase *IntuitionBase;
  21.  
  22. struct Window *WindowUnderPointer();
  23.  
  24. /* With any luck this will fix reported CyberGuard hits with MUI programs. */
  25. struct
  26. {
  27.   char a,b,c,d;
  28. } DeadKeyData;
  29.  
  30.  
  31. void SendIDCMP(struct WheelMouseContext *wmc,int class,int code,int qualifier,struct IntuiMessage *im)
  32. {
  33.   struct Window *win=wmc->Window;
  34.   struct Gadget *gg=wmc->Gadget;
  35.   im->IDCMPWindow=win;
  36.   if(class==IDCMP_RAWKEY)
  37.     im->IAddress=&DeadKeyData;
  38.   else
  39.     im->IAddress=gg;
  40.   im->Class=class;
  41.   im->Code=code;
  42.   im->Qualifier=qualifier;
  43.   im->MouseX=win->MouseX;
  44.   im->MouseY=win->MouseY;
  45.   im->ExecMessage.mn_ReplyPort=wmc->ReplyPort;
  46.   im->Seconds=IntuitionBase->Seconds; im->Micros=IntuitionBase->Micros;
  47.   im->SpecialLink=NULL;
  48.   PutMsg(win->UserPort,(struct Message *)im);
  49. }
  50.  
  51.  
  52. void NudgePropGadget(struct WheelMouseContext *wmc,int axis,int direction)
  53. {
  54.   struct Window *win=wmc->Window;
  55.   struct Gadget *gg=wmc->Gadget;
  56.   struct PropInfo *pi=(struct PropInfo *)gg->SpecialInfo;
  57.  
  58.   long current,offset;
  59.  
  60.   if(axis&FREEVERT)
  61.   {
  62.     current=pi->VertPot;
  63.     offset=pi->VPotRes;
  64.     current+=(direction*offset*wmc->ScrollSpeedY)/32;
  65.     if(current<0) current=0;
  66.     if(current>0xffff) current=0xffff;
  67.     pi->VertPot=current;
  68.   }
  69.  
  70.   if(axis&FREEHORIZ)
  71.   {
  72.     current=pi->HorizPot;
  73.     offset=pi->HPotRes;
  74.     current+=(direction*offset*wmc->ScrollSpeedX)/32;
  75.     if(current<0) current=0;
  76.     if(current>0xffff) current=0xffff;
  77.     pi->HorizPot=current;
  78.   }
  79.  
  80. }
  81.  
  82.  
  83. struct Gadget *FindPropGadget(struct Window *win,long type)
  84. {
  85.   struct Gadget *gg=win->FirstGadget,*bestgadget=NULL;
  86.   int gx,gy,gt,gl,gw,gh,dd,distance=32767;
  87.   while(gg)
  88.   {
  89.     if(((gg->GadgetType>YP_GTYPEMASK)==GTYP_PROPGADGET)&&(gg->Flags&GFLG_DISABLED)==0)
  90.     {
  91.       struct PropInfo *pi=(struct PropInfo *)gg->SpecialInfo;
  92.       if(pi)
  93.       {
  94.         if(pi->Flags&type)
  95.         {
  96.           dd=32767;
  97.  
  98.           gl=gg->LeftEdge; gt=gg->TopEdge;
  99.           gw=gg->Width; gh=gg->Height;
  100.           if(gg->Flags&GFLG_RELRIGHT)
  101.             gl+=win->Width;
  102.           if(gg->Flags&GFLG_RELBOTTOM)
  103.             gt+=win->Height;
  104.           if(gg->Flags&GFLG_RELWIDTH)
  105.             gw+=win->Width;
  106.           if(gg->Flags&GFLG_RELHEIGHT)
  107.             gh+=win->Height;
  108.  
  109.           if(pi->Flags&FREEVERT)
  110.           {
  111.             gx=gl+gw;
  112.  
  113.             dd=gx-win->MouseX;
  114.             if(dd<0)
  115.               dd=-dd+win->Width; /* bias to left of scrollbar */
  116.             gy=(gt+gh)-win->MouseY;
  117.             if((gt-win->MouseY)*(gt-win->MouseY)<(gy*gy))
  118.               gy=gt-win->MouseY;
  119.             if(gy<0)
  120.               gy=-gy;
  121.             dd+=gy;
  122.           }
  123.           if(pi->Flags&FREEHORIZ)
  124.           {
  125.             if(type==(FREEHORIZ|FREEVERT))
  126.             {
  127.               gx=win->MouseX-gl;
  128.               gy=win->MouseY-gt;
  129.               if((gx>=-2)&&(gy>=-2)&&(gx<=(gw+2))&&(gy<=(gh+2)))
  130.                 dd=1;
  131.             }
  132.             else
  133.             {
  134.               gy=gt+gh;
  135.  
  136.               dd=gy-win->MouseY;
  137.               if(dd<0)
  138.                 dd=-dd+win->Height; /* bias to top of scrollbar */
  139.               gy=(gl+gw)-win->MouseX;
  140.               if((gt-win->MouseX)*(gt-win->MouseX)<(gy*gy))
  141.                 gy=gt-win->MouseX;
  142.               if(gy<0)
  143.                 gy=-gy;
  144.               dd+=gy;
  145.             }
  146.           }
  147.           if(dd<0) dd=-dd;
  148.           if(dd<distance)
  149.           {
  150.             distance=dd;
  151.             bestgadget=gg;
  152.           }
  153.         }
  154.       }
  155.     }
  156.     gg=gg->NextGadget;
  157.   }
  158.   return(bestgadget);
  159. }
  160.  
  161.  
  162. int DoScroll(struct WheelMouseContext *wmc,int axis,int direction)
  163. {
  164.   struct Window *win;
  165.  
  166.   Forbid();
  167.   if(wmc->WindowMode==OverWindow)
  168.     win=wmc->Window=WindowUnderPointer();
  169.   else
  170.     win=wmc->Window=IntuitionBase->ActiveWindow;
  171.   if(!(win))
  172.     return(direction);
  173.   wmc->Gadget=FindPropGadget(win,axis);
  174.   if((!(wmc->Gadget))&&(wmc->WindowMode==OverWindow)&&((win->IDCMPFlags&IDCMP_RAWKEY)==0))
  175.   {
  176.     if(!(win=wmc->Window=IntuitionBase->ActiveWindow))
  177.       return(direction);
  178.     wmc->Gadget=FindPropGadget(win,axis);
  179.   }
  180.  
  181.   if((wmc->Gadget)&&(wmc->NudgeProp))
  182.   {
  183.     if(win->UserPort->mp_SigTask!=wmc->MainTask)
  184.     {
  185.       NudgePropGadget(wmc,axis,direction);
  186.       SendIDCMP(wmc,IDCMP_GADGETDOWN,0,0,&wmc->Msg1.eim_IntuiMessage);
  187.       SendIDCMP(wmc,IDCMP_GADGETUP,0,0,&wmc->Msg2.eim_IntuiMessage);
  188.       RefreshGList(wmc->Gadget,wmc->Window,NULL,1);
  189.       Permit();
  190.       WaitPort(wmc->ReplyPort);
  191.       GetMsg(wmc->ReplyPort);
  192.       WaitPort(wmc->ReplyPort);
  193.       GetMsg(wmc->ReplyPort);
  194.     }
  195.     else
  196.       Permit();
  197.     return(direction);
  198.   }
  199.   else if((win->IDCMPFlags&IDCMP_RAWKEY)&&(wmc->ForgeRawKey))
  200.   {
  201.     int code,c,d,q=0;
  202.     d=direction;
  203.     if(d>0)
  204.       if(axis&FREEVERT)
  205.         code=RK_Down;
  206.       else
  207.         code=RK_Right;
  208.     else
  209.     {
  210.       if(axis&FREEVERT)
  211.         code=RK_Up;
  212.       else
  213.         code=RK_Left;
  214.       d=-d;
  215.     }
  216.     if((d>wmc->PageThreshold)&&(wmc->RawKeyPage))
  217.       q=IEQUALIFIER_LSHIFT;
  218.     else
  219.       direction/=d; /* either 1 or -1 */
  220.  
  221.     if(win->UserPort->mp_SigTask!=wmc->MainTask)
  222.     {
  223.       SendIDCMP(wmc,IDCMP_RAWKEY,code,q,&wmc->Msg1.eim_IntuiMessage);
  224.       SendIDCMP(wmc,IDCMP_RAWKEY,code|IECODE_UP_PREFIX,q,&wmc->Msg2.eim_IntuiMessage);
  225.       Permit();
  226.       WaitPort(wmc->ReplyPort);
  227.       GetMsg(wmc->ReplyPort);
  228.       WaitPort(wmc->ReplyPort);
  229.       GetMsg(wmc->ReplyPort);
  230.     }
  231.     else
  232.       Permit();
  233.     return(direction);
  234.   }
  235.   Permit();
  236.   return(direction);
  237. }
  238.  
  239.  
  240. struct Window *WindowUnderPointer()
  241. {
  242.   int x,y;
  243.   unsigned long lock;
  244.   struct Window *win=NULL;
  245.   struct Screen *scr;
  246.   struct Layer *layer;
  247.  
  248.   scr=IntuitionBase->FirstScreen;
  249.   do
  250.   {
  251.     x=scr->MouseX; y=scr->MouseY;
  252.     if((x<0) || (y<0))
  253.       scr=scr->NextScreen;
  254.   } while((scr!=NULL) && ((x<0)||(y<0)));
  255.  
  256.   if(!scr)
  257.     return(NULL);
  258.  
  259.   layer=WhichLayer(&scr->LayerInfo,x,y);
  260.   if(layer)
  261.     win=layer->Window;
  262.   return(win);
  263. }
  264.  
  265.